package example.springboot.util;

import example.springboot.entity.SystemLog;
import example.springboot.service.SystemLogService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;

/**
 *
 * @Author 董熠涛
 * @Date 2025/6/16 20:22
 */
@Component
public class SystemLogUtil implements ApplicationContextAware {

    private static SystemLogService systemLogService;
    private static JwtUtil jwtUtil;
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SystemLogUtil.applicationContext = applicationContext;
        SystemLogUtil.systemLogService = applicationContext.getBean(SystemLogService.class);
        SystemLogUtil.jwtUtil = applicationContext.getBean(JwtUtil.class);
    }

    /**
     * 获取客户端IP地址
     */
    private static String getClientIp(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }
        
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        
        // 处理多个IP的情况，取第一个
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        
        // 将IPv6的localhost转换为IPv4的localhost
        if ("0:0:0:0:0:0:0:1".equals(ip) || "::1".equals(ip)) {
            ip = "127.0.0.1";
        }
        
        return ip != null ? ip : "unknown";
    }

    /**
     * 获取当前请求对象
     */
    private static HttpServletRequest getRequest() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            return attributes != null ? attributes.getRequest() : null;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 从请求头中获取当前登录用户名
     */
    private static String getCurrentUsername() {
        try {
            HttpServletRequest request = getRequest();
            if (request == null) {
                return "system";
            }
            
            String authHeader = request.getHeader("Authorization");
            if (authHeader != null && authHeader.startsWith("Bearer ")) {
                String token = authHeader.substring(7);
                if (jwtUtil != null && jwtUtil.validateToken(token)) {
                    return jwtUtil.getUsernameFromToken(token);
                }
            }
            return "system";
        } catch (Exception e) {
            return "system";
        }
    }

    /**
     * 记录操作日志
     * 
     * @param type 日志类型：login-登录日志, operation-操作日志, error-错误日志
     * @param username 操作用户名
     * @param action 操作动作
     * @param content 日志内容
     */
    public static void log(String type, String username, String action, String content) {
        try {
            // 如果service还未注入，直接返回，避免空指针异常
            if (systemLogService == null) {
                System.err.println("SystemLogService is null, cannot log: " + action);
                return;
            }
            
            HttpServletRequest request = getRequest();
            String ip = getClientIp(request);
            
            SystemLog log = new SystemLog();
            log.setType(type);
            log.setUsername(username != null ? username : "system");
            log.setAction(action);
            log.setIp(ip);
            log.setContent(content);
            // created_at 由数据库自动设置，不需要手动设置
            
            systemLogService.createSystemLog(log);
            System.out.println("[SystemLog] Recorded: " + type + " - " + action + " by " + username + " from " + ip);
        } catch (Exception e) {
            // 日志记录失败不应该影响主业务流程
            System.err.println("Failed to log: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 记录登录日志
     */
    public static void logLogin(String username, boolean success) {
        if (success) {
            log("login", username, "用户登录", "管理员登录系统");
        } else {
            log("error", username, "登录失败", "管理员登录失败");
        }
    }

    /**
     * 记录操作日志（自动获取当前登录用户）
     */
    public static void logOperation(String action, String content) {
        String username = getCurrentUsername();
        log("operation", username, action, content);
    }

    /**
     * 记录操作日志（指定用户名）
     */
    public static void logOperation(String username, String action, String content) {
        log("operation", username, action, content);
    }

    /**
     * 记录错误日志（自动获取当前登录用户）
     */
    public static void logError(String action, String content) {
        String username = getCurrentUsername();
        log("error", username, action, content);
    }

    /**
     * 记录错误日志（指定用户名）
     */
    public static void logError(String username, String action, String content) {
        log("error", username, action, content);
    }
}

